package cn.shujuhai.qtadmin.platform.pluging.repeatsubmit;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import cn.shujuhai.qtadmin.platform.pluging.result.Result;
import lombok.extern.slf4j.Slf4j;

/**
 * NoRepeatSubmitAop
 *
 * @author dch798
 * @date 2021/10/13 20:03
 *
 **/

@Slf4j
@Aspect
@Component
public class NoRepeatSubmitAspect {

    private static final Cache<String, Object> CACHES = CacheBuilder.newBuilder()
        // 最大缓存 100 个
        .maximumSize(1000)
        // 设置写缓存后 10 秒钟过期
        .expireAfterWrite(10, TimeUnit.SECONDS).build();

    /**
     *
     * @param joinPoint
     *            joinPoint
     * @param nos
     *            nos
     * @return return
     *
     */
    @Around("execution(* cn.shujuhai.qtadmin.platform.controller..*.*(..))&& @annotation(nos)")
    public Object arround(ProceedingJoinPoint joinPoint, RepeatSubmit nos) {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
            String sessionId = Objects.requireNonNull(attributes).getSessionId();
            HttpServletRequest request = attributes.getRequest();
            String key = sessionId + "-" + request.getServletPath();
            if (CACHES.getIfPresent(key) == null) {
                CACHES.put(key, key);
                return joinPoint.proceed();
            } else {
                log.error("重复提交");
                return Result.failure("重复提交");
            }
        } catch (Throwable throwable) {
            log.error("验证重复提交时出现未知异常!");
            return Result.failure("验证重复提交时出现未知异常!");
        }
    }
}
